package cn.com.goldhs.architecture.inter.impl;

import java.util.List;
import java.util.ResourceBundle;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.EmbeddedGraphDatabase;

import cn.com.goldhs.architecture.inter.ArchitectureService;
import cn.com.goldhs.architecture.inter.Base;
import cn.com.goldhs.architecture.inter.Department;
import cn.com.goldhs.architecture.inter.Leader;

public class ArchitectureServiceImpl implements ArchitectureService {

	private static ResourceBundle res = ResourceBundle
			.getBundle("architecture");

	enum RootShipTypes implements RelationshipType {
		LeaderRootShip
	}

	private GraphDatabaseService mService = null;
	private Transaction tx = null;

	public ArchitectureServiceImpl(String path) {
		mService = new EmbeddedGraphDatabase(path);
	}

	@Override
	public void shutdown() {
		mService.shutdown();
	}

	@Override
	public void beginTx() {
		tx = mService.beginTx();
	}

	@Override
	public void commitTx() {
		tx.success();
		tx.finish();
	}

	@Override
	public void rollbackTx() {
		tx.finish();
	}

	@Override
	public Leader createLeader(String name, Leader superLeader) {
		if(!exists(name)) {
			Leader leader = new LeaderImpl(mService.createNode());
			leader.setName(name);
			superLeader.addSubLeader(leader);
			
			return leader;
		}else 
			
			return null;
	}

	@Override
	public Department createDepartment(String name, Base parent) {
		if(!exists(name)) {
			Department dept = new DepartmentImpl(mService.createNode());
			dept.setName(name);
			parent.addSubDept(dept);
			
			return dept;
		} else 
			return null;
	}

	@Override
	public void moveLeadersToLeader(List<Leader> leaders, Leader leader) {
		for (Leader l : leaders) {
			l.moveToLeader(leader);
		}
	}

	@Override
	public void moveDeptsToBases(List<Department> depts, Base base) {
		for (Department d : depts) {
			d.moveToBase(base);
		}
	}
	
	@Override
	public void remove(List<Base> bases) {
		for (Base b : bases) {
			b.remove();
		}
	}

	@Override
	public Leader getRootNode() {
		Node refNode = mService.getReferenceNode();
		if(!refNode.hasProperty("Name"))
			refNode.setProperty("Name", res.getString("Root.Name"));
		
		return new LeaderImpl(refNode);
	}
	
	public boolean exists(String name) {
		for (Node node : mService.getAllNodes()) {
			if(node.hasProperty("Name") && node.getProperty("Name").equals(name))
				return true;
		}
		
		return false;
	}
	
}